package com.nd.rj.common.login;

import java.util.ArrayList;
import java.util.UUID;

import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;

import com.common.StarAppConfig;
import com.common.StarAppConst;
import com.common.allCommon.JSONObjecthelper;
import com.common.utils.EncryptTool;
import com.nd.rj.common.R;
import com.nd.rj.common.login.DataDef.NdLoginConst;
import com.nd.rj.common.login.atomoperation.OperUserInfo;
import com.nd.rj.common.login.communication.uapCom;
import com.nd.rj.common.login.dbreposit.CfgDBHelper;
import com.nd.rj.common.login.entity.ClientInfo;
import com.nd.rj.common.util.db.IDataBaseRef;
import com.product.android.business.ApplicationVariable;
import com.product.android.business.bean.UserInfo;

public class LoginPro {
    private static final String tag = "debug";
    private static LoginPro mLoginPro;
    /** 验证码类型，=4 发送手机注册验证码*/
    public  static final int REG_TYPE = 4;
    /** 注册类型，=1 通用手机注册*/
    public  static final int REG_bTYPE = 1;
    private IDataBaseRef mDBHelper;

    private Context ctx;

    private LoginPro(Context context) {
        mDBHelper = CfgDBHelper.getInstance();
        mDBHelper.open(context.getApplicationContext(), null);
        ctx = context;
    }

    public static LoginPro getInstance(Context context) {
        if (mLoginPro == null) {
            mLoginPro = new LoginPro(context);
        }
        
        //如果DB帮助类已经，这里重新打开
        if(!mLoginPro.mDBHelper.DbValid()){
            mLoginPro.mDBHelper = CfgDBHelper.getInstance();
            mLoginPro.mDBHelper.open(context.getApplicationContext(), null);
        }
        
        return mLoginPro;
    }

    /**
     * 使用票据登录
     * 
     * @param type
     *            登录的类型：OAP、UAP
     * @param user
     *            用户信息
     * @param clientInfo
     *            终端信息
     * @param errmsg
     * @return
     */
    public int userLoginByTicket(int type, UserInfo user, ClientInfo clientInfo,
            StringBuilder errmsg) {
        switch (type) {
        case NdLoginConst.LOGIN_TYPE_UAP:
            Log.d(tag, "userLoginByTicket:UAP");
            return loginUapByTicket(user, errmsg);
        case NdLoginConst.LOGIN_TYPE_OAP:
        default:
            return -1;
        }
    }

    public int userLoginByTicket(int type, UserInfo user, int unitid, long uid,
            ClientInfo clientInfo, StringBuilder errmsg) {
        return loginUapByTicket(user, errmsg);
    }

    public int userLoginByTicket(int type, UserInfo user, StringBuilder errmsg) {
        return userLoginByTicket(type, user, null, errmsg);
    }

    public int userLoginByTicket(int type, UserInfo user, int unitid, long uid, StringBuilder errmsg) {
        return userLoginByTicket(type, user, unitid, uid, null, errmsg);
    }

    public int userLoginByCookie(int type, String cookie, UserInfo user, ClientInfo clientInfo,
            StringBuilder receive) {
        return loginUapByCookie(cookie, user, receive);
    }

    private String getUserNickName(long uid, String sid) {
        String nickname = null;
        StringBuilder receive = new StringBuilder();
        final int iret = uapCom.getInstance(ctx).getUserInfo(uid, sid, receive);
        if (iret == 0) {
            try {
                JSONObject json = new JSONObject(receive.toString());
                nickname = json.getString("nickname");
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return nickname;
    }

    /**
     * @Title: userRegist
     * @Description: 普通注册接口
     * @author yanyy
     * @date 2013-2-19 下午3:38:47
     * 
     * @param type
     *            (0 uap 1 oap)
     * 
     * @param user
     * @param errmsg
     * @return
     * @return int
     * @throws
     */
    public int userRegist(int type, UserInfo user, StringBuilder errmsg) {
        errmsg.delete(0, errmsg.length());
        StringBuilder receive = new StringBuilder();
        int ireturn = uapCom.getInstance(ctx).userRegister(user.getUserName(), user.getUserPass(),
                user.getUserNickName(), user.getBlowfish(), receive);
        if (ireturn == 0) {
            try {
                JSONObject json = new JSONObject(receive.toString());
                user.setSessionId(json.getString("sid"));
                user.setUapUid(json.getLong("uid"));
                // 为了避免改动到allcommon，这边把所有的UAP登录的时候的OAPUID也设置成UID
                user.setOapUid(json.getLong("uid"));
                user.setUserName(json.getString("username"));
                user.setTicket(json.getString("ticket"));
                ireturn = OperUserInfo.getInstance().SetUserInfo(user);
            } catch (JSONException e) {
                e.printStackTrace();
                ireturn = R.string.nd_json_error;
            }
        } else {
            errmsg.append(receive);
        }
        return ireturn;
    }

    /**
     * 发送短信验证码
     * 
     * @Title: sendCode
     * @Description: TODO
     * @author chenyw
     * @date 2012-6-18
     * @param @param phone
     * @param @param receive
     * @param @return
     * @return int
     * @throws
     */
    public int sendCode(String phone, String type, StringBuilder errmsg) {
        errmsg.delete(0, errmsg.length());
        StringBuilder receive = new StringBuilder();
        int ireturn = uapCom.getInstance(ctx).sendCode(phone, type, receive);

        // 得到错误信息
        if (0 != ireturn) {
            if (0 == receive.length()) {
                getErrMsgIfNoReceive(errmsg, ireturn);
            } else {
                errmsg.append(receive);
            }
        }

        return ireturn;
    }

    /**
     * @Title: regPhone
     * @Description: 手机注册接口
     * @author yanyy
     * @date 2013-2-19 下午3:43:31
     * 
     * @param type
     *            (0 uap 1 oap)
     * @param user
     * @param verifycode
     * @param errmsg
     * @return
     * @return int
     * @throws
     */
    public int regPhone(int type, UserInfo user, String verifycode, StringBuilder errmsg) {
        errmsg.delete(0, errmsg.length());
        StringBuilder receive = new StringBuilder();
        int ireturn = uapCom.getInstance(ctx).regPhone(user.getUserName(), user.getUserPass(),
                verifycode, user.getBlowfish(), receive);
        if (ireturn == 0) {
            // 成功就直接登陆
            // 记录用户信息
            try {
                JSONObject json = new JSONObject(receive.toString());
                user.setSessionId(json.getString("sid"));
                // 为了避免改动到allcommon，这边把所有的UAP登录的时候的OAPUID也设置成UID
                user.setUapUid(json.getLong("uid"));
                user.setOapUid(json.getLong("uid"));
                user.setTicket(json.getString("ticket"));
                // 密码加密
                user.setUserPass(NdLoginComFun.RSAEncrypt(user.getUserPass(), NdLoginConst.MODULUS,
                        NdLoginConst.PUBEXP));
                user.setUserPassMixedMd5(EncryptTool.getMD5str(user.getUserPass(),
                        EncryptTool.TYPE_PSW).toLowerCase());
                ireturn = OperUserInfo.getInstance().SetUserInfo(user);
            } catch (JSONException e) {
                e.printStackTrace();
                errmsg.append(ctx.getString(R.string.nd_json_error));
            }
        } else {
            if (ireturn == 1) {
                try {
                    JSONObject json = new JSONObject(receive.toString());
                    if (json != null) {
                        errmsg.append(JSONObjecthelper.getString(json, "msg"));
                    }
                    return ireturn;
                } catch (JSONException e) {
                    e.printStackTrace();
                    errmsg.append(ctx.getString(R.string.nd_json_error));
                }
            } else if (ireturn == HttpStatus.SC_NO_CONTENT) {
                errmsg.append(ctx.getString(R.string.nd_code_wrong));
            } else {
                if (0 == receive.length()) {
                    getErrMsgIfNoReceive(errmsg, ireturn);
                } else {
                    errmsg.append(receive);
                }
            }
        }
        return ireturn;
    }

    /**
     * 判断是否可以注册 <br>
     * Created 2014-9-5 下午3:23:13
     * 
     * @param strPhone
     *            注册手机号
     * @return 200 可以注册 （1、用户不存在；2、多绑相关：当前登陆帐号允许绑定；3、用户没有绑定密宝手机） 406 帐号格式不合法 409 其他原因导致无法注册
     * @author gpy
     */
    public int isRegistered(String strPhone) {
        if (TextUtils.isEmpty(strPhone)) {
            return HttpStatus.SC_CONFLICT;
        }
        return uapCom.getInstance(ctx).isRegistered(strPhone);
    }
    
    /**
     * 改绑密保手机
     * 
     * <br>
     * Created 2014-9-9 上午10:21:26
     * 
     * @param uid
     *            必填，用户ID（11位整型）
     * @param oldPhone
     *            必填，旧密保手机号码（11位整型）
     * @param newPhone
     *            必填，新密保手机号码（11位整型）
     * @param verifycode
     *            必填，手机验证码，需要先下发到用户手机（随机字符串）
     * @return 200 绑定密保手机成功; 204 旧密保手机为空/新密保手机为空/短信验证码为空/短信验证码不正确; 404 用户不存在; 411 改绑密保手机失败 409
     *         其他原因导致
     * @author gpy
     */
    public int changePhone(long uid, String oldPhone, String newPhone, String verifycode) {
        if (TextUtils.isEmpty(oldPhone) || TextUtils.isEmpty(newPhone)
                || TextUtils.isEmpty(verifycode)) {
            return HttpStatus.SC_LENGTH_REQUIRED;
        }
        return uapCom.getInstance(ctx).changePhone(uid, oldPhone, newPhone, verifycode);
    }

    /**
     * 
     * <br>
     * Created 2014-9-9 上午11:47:47
     * 
     * @param uid
     *            必填，修改用户的帐户ID
     * @param sid
     *            登录SID
     * @param oldPwd
     *            旧密码，6-12位字符
     * @param newPwd
     *            新密码，6-12位字符
     * @param cfmPwd
     *            确认密码，6-12位字符
     * @return 200 恭喜，密码重置成功 204 旧密码/新密码/确认密码 有空的情况 205 新密码和确认密码不同 304 旧密码错误 403 不属于特殊用户 404 用户不存在
     *         406 新密码/确认密码/密码格式错误,允许6-12字符，可以包括数字,字母,区分大小写 417 用户不是登录状态 501 密码修改不成功
     * @author gpy
     */
    public int changePwd(long uid, String sid, String oldPwd, String newPwd, String cfmPwd) {
        if (TextUtils.isEmpty(sid) || TextUtils.isEmpty(oldPwd) || TextUtils.isEmpty(newPwd)
                || TextUtils.isEmpty(cfmPwd)) {
            return HttpStatus.SC_NOT_IMPLEMENTED;
        }
        return uapCom.getInstance(ctx).changePwd(uid, sid, oldPwd, newPwd, cfmPwd);
    }

    /**
     * 出错时，接口可能没有返回错误信息，这里根据返回码（资源值）去取，取不到就提示未知错误 <br>
     * Created 2014-5-22 下午9:37:47
     * 
     * @param errmsg
     *            StringBuilder，用于返回错误信息给调用者
     * @param iReturn
     *            接口返回码
     * @author : linsj
     */
    private void getErrMsgIfNoReceive(StringBuilder errmsg, int iReturn) {
        try {
            errmsg.append(ctx.getString(iReturn));
        } catch (Exception e) {
            errmsg.append(ctx.getString(R.string.nd_unknow_error)).append(iReturn);
        }
    }

    /**
     * @Title: getUserList
     * @Description: 获取用户列表
     * @author Administrator
     * @date 2012-2-1 下午04:35:54
     * @return
     * @return ArrayList<UserInfo>
     * @throws
     */
    public ArrayList<UserInfo> getUserList() {
        ArrayList<UserInfo> users = new ArrayList<UserInfo>();
        Cursor cur = mDBHelper.querySql("select * from USERINFO order by LAST_LOGIN_DT desc");
        try {
            if ((cur != null) && (cur.getCount() > 0)) {
                while (cur.moveToNext()) {
                    UserInfo user = new UserInfo();
                    user.LoadFormCursor(cur);
                    users.add(user);
                }
            }
        } finally {
            CfgDBHelper.closeCursor(cur);
        }
        return users;
    }

    /**
     * @Title: getLastUserInfo
     * @Description: (获取最后一次登陆的用户信息)
     * @author Administrator
     * @date 2012-2-2 下午02:01:03
     * @return
     * @return UserInfo
     * @throws
     */
    public UserInfo getLastUserInfo() {
        return OperUserInfo.getInstance().GetLastUserInfo();
    }

    /**
     * <br>
     * Description:TODO 切换组织后保存组织ID，以便下次自动登录到该组织 <br>
     * Author:daiyf <br>
     * Date:2013-6-5下午2:28:58
     * 
     * @param unitid
     * @param oap_uid
     */
    public void updateLastUserInfo(long unitid, long oap_uid) {
        OperUserInfo.getInstance().UpdateLastUserInfo(unitid, oap_uid);
    }

    /**
     * @Title: logOut
     * @Description: (登出)
     * @author Administrator
     * @date 2012-2-2 下午05:33:45
     * @param uid
     * @param sid
     * @return void
     * @throws
     */
    public void logOut(long uid, String sid) {
        uapCom.getInstance(ctx).logOut(uid, sid);
    }

    /**
     * @Title: deleteUser
     * @Description: (删除)
     * @author Administrator
     * @date 2012-2-6 下午03:05:57
     * @param uid
     * @return void
     * @throws
     */
    public void deleteUser(long uid) {
        OperUserInfo.getInstance().DeleteUserInfo(uid);
    }

    /**
     * @Title: getWlSid
     * @Description: TODO(获取无线sid)
     * @author Administrator
     * @date 2012-2-9 下午03:17:43
     * @param uid
     *            {uap_uid}
     * @param siteid
     *            {帐号类型}
     * @param outSid
     *            {输出sid}
     * @param errmsg
     *            {错误信息}
     * @return
     * @return int
     * @throws
     */
    public int getWlSid(long uid, int siteid, String sid, StringBuilder outSid, StringBuilder errmsg) {
        errmsg.delete(0, errmsg.length());
        outSid.delete(0, outSid.length());
        StringBuilder receive = new StringBuilder();
        Log.d("debug", "uid=" + uid + ",siteid=" + siteid);
        int ireturn = uapCom.getInstance(ctx).getWlSid(uid, siteid, sid, receive);
        if (ireturn == 0) {
            try {
                JSONObject json = new JSONObject(receive.toString());
                JSONObject ajson = json.getJSONObject("charge");
                String wlsid = ajson.getString("SessionId");
                outSid.append(wlsid);
            } catch (JSONException e) {
                e.printStackTrace();
                Log.d("debug", receive.toString());
                ireturn = R.string.nd_json_error;
            }
        } else {
            errmsg.append(receive);
        }
        return ireturn;
    }

    /**
     * @Title: setUserInfo
     * @Description: TODO(保存用户信息)
     * @author yanyy
     * @date 2012-9-24 上午09:26:09
     * 
     * @param user
     * @return
     * @return int
     * @throws
     */
    public int setUserInfo(UserInfo user) {
        return OperUserInfo.getInstance().SetUserInfo(user);
    }

    /**
     * @Title: getUserByUserName
     * @Description: TODO(根据帐号获取用户信息)
     * @author yanyy
     * @date 2012-11-9 下午05:06:16
     * 
     * @param username
     * @return
     * @return UserInfo
     * @throws
     */
    public UserInfo getUserByUserName(String username) {
        return OperUserInfo.getInstance().GetUserByUserName(username);
    }

    /**
     * @Title: deleteAllUsers
     * @Description: TODO(删除所有用户)
     * @author yanyy
     * @date 2012-11-12 上午10:42:07
     * 
     * @return void
     * @throws
     */
    public int deleteAllUsers() {
        return OperUserInfo.getInstance().deleteAllUsers();
    }

    /**
     * @Title: clearPassWord
     * @Description: TODO(清除密码)
     * @author yanyy
     * @date 2012-11-12 上午11:04:01
     * 
     * @return
     * @return int
     * @throws
     */
    public int clearPassWord(long uap_uid) {
        return OperUserInfo.getInstance().clearUserPassWord(uap_uid);
    }

    /**
     * @Title: checkSessionId
     * @Description: TODO(验证sid)
     * @author yanyy
     * @date 2012-12-3 下午06:01:28
     * 
     * @param ctx
     * @param sid
     * @return
     * @return long
     * @throws
     */
    public long checkSessionId(Context ctx, String sid) {
        long uid = 0;
        StringBuilder receive = new StringBuilder();
        int ireturn = uapCom.getInstance(ctx).checkSession(sid, receive);
        if ((ireturn == 0) && (receive.length() > 0)) {
            try {
                JSONObject j = new JSONObject(receive.toString());
                uid = j.getLong("uid");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return uid;
    }

    /**
     * 设置扩展字段的值
     * 
     * @param uap_uid
     * @param var_ext
     * @return
     */

    public int setExtInfo(long uap_uid, String var_ext) {
        return OperUserInfo.getInstance().setExtInfo(uap_uid, var_ext);
    }

    /**
     * @n<b>函数名称</b> :loginUapByCookie
     * @brief 使用cookie登录UAP
     * @see
     * @since Ver 1.1
     * 
     * @param @param cookie
     * @param @param user
     * @param @param receive
     * @param @return
     * @return int
     * @<b>作者</b> : cb
     * @<b>创建时间</b> : 2013-5-22上午11:15:05
     */
    private int loginUapByCookie(String cookie, UserInfo user, StringBuilder receive) {
        receive.delete(0, receive.length());
        String blowfish = UUID.randomUUID().toString();
        int ireturn = uapCom.getInstance(ctx).getTicketByCookie(cookie, blowfish, user, receive);
        if (ireturn == 0 && receive.length() > 0) {
            try {
                JSONObject object = new JSONObject(receive.toString());
                String ticket = object.getString("ticket");
                user.setBlowfish(blowfish);
                user.setTicket(ticket);
                setUserInfo(user, object);
                String nickname = getUserNickName(user.getUapUid(), user.getSessionId());
                if (!TextUtils.isEmpty(nickname)) {
                    user.setUserNickName(nickname);
                }
                ireturn = OperUserInfo.getInstance().SetUserInfo(user);
                // Log.d("debug",
                // "getTicketByCookie:uid="+uid+",sid="+sid+",ticket="+ticket+",nickname="+nickname);
                
                // TODO 充值模块 启用：注释去掉
                //保存token
                SharedPreferences sp = ApplicationVariable.INSTANCE.applicationContext
                        .getSharedPreferences(StarAppConst.PAY.PAY_SHAREDPREFERENCES,
                                Activity.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();

                String token = "";
                try {
                    token = EncryptTool.byte2Hex(
                                EncryptTool.desEncrypt(
                                        StarAppConfig.getConfig(StarAppConfig.CONFIG_PAY_TOKEN),
                                        StarAppConst.PAY.PAY_ENCRYPT_KEY));
                } catch (Exception e) {
                    if(!TextUtils.isEmpty(e.getMessage())){
                        Log.e("NdRegistManagerImpl", e.getMessage());
                    }
                    token = "";
                }

                editor.putString(user.getUapUid()+"", token);
                editor.commit();
            } catch (JSONException e) {
                ireturn = R.string.nd_json_error;
                e.printStackTrace();
            }
        }
        return ireturn;
    }

    /**
     * 
     * @函数名称 :setUserInfo
     * @brief 重复代码抽成方法
     * @see
     * @since Ver 1.1
     * @param user
     * @param object
     * @throws JSONException
     * @作者 : huangszh
     * @创建时间 : 2014-4-29下午3:56:57
     */
    private void setUserInfo(UserInfo user, JSONObject object) throws JSONException {
        long uid = object.getLong("uid");
        String sid = object.getString("sid");
        user.setUapUid(uid);
        // 为了避免改动到allcommon，这边把所有的UAP登录的时候的OAPUID也设置成UID
        user.setOapUid(uid);
        user.setSessionId(sid);
        user.sex = object.optInt("sex");
        user.prestige = object.optInt("prestige");
        user.wealth = object.optInt("wealth");
        user.flower = object.optInt("flower");
        user.grade = object.optInt("grade");
        user.realname = object.optString("realname");
        user.uniquename = object.optString("uniquename");
        user.dataline = object.optLong("dateline");
    }

    /**
     * @n<b>函数名称</b> :loginUapByTicket
     * @brief　使用票据登录UAP
     * @see
     * @since Ver 1.1
     * 
     * @param @param user
     * @param @param receive
     * @param @return
     * @return int
     * @<b>作者</b> : cb
     * @<b>创建时间</b> : 2013-5-22上午11:15:28
     */
    private int loginUapByTicket(UserInfo user, StringBuilder receive) {
        receive.delete(0, receive.length());
        String ticket = user.getTicket();
        String blowfish = user.getBlowfish();
        if (TextUtils.isEmpty(blowfish) || TextUtils.isEmpty(ticket)) {
            return R.string.nd_login_ticket_403;
        }
        int ireturn = uapCom.getInstance(ctx).userLoginTicket(ticket, blowfish, receive);
        if (ireturn == 0 && receive.length() > 0) {
            try {
                JSONObject object = new JSONObject(receive.toString());
                setUserInfo(user, object);
                ireturn = OperUserInfo.getInstance().SetUserInfo(user);
                Log.d("debug",
                        "userLoginTicket:uid=" + user.getUapUid() + ",sid=" + user.getSessionId());
            } catch (JSONException e) {
                ireturn = R.string.nd_json_error;
                e.printStackTrace();
            }
        }
        return ireturn;
    }
}
